﻿import re,os,datetime

class Object(object):
    pass

class Myjson(object):
    def __init__(self,content=''):
        self.content=content
        self.coding_list=['utf-8', 'gb2312', 'gbk', 'gb18030']
    def decode_str(self,data):
        for coding in self.coding_list:
            try:
                rdata=data.decode(coding)
                return rdata
            except:
                pass
        return data.decode('utf-8','ignore')

    def encode_attr(self,tobject,svalue):
        if str(svalue).startswith('__'):
            return ''
        if hasattr(tobject,str(svalue)):
            value=getattr(tobject,str(svalue))
        else:
            value=svalue
        if '__call__' in dir(value):
            return ''
        if type(value) in (type(1),type(1L),type(1.0)):
            return '%s'%value
        elif type(value)==type(True):
            return '%s'%(str(value).lower())
        elif type(value)==type('s'):                    #str
            #print "%s:%s,"%(str(svalue),str(value))
            value=self.decode_str(value)
            print '"%s"'%value
            return '"%s"'%value
        elif type(value)==type(None):                   #None
            return 'null'
        elif type(value)==type([1]):                    #list
            return_list=[]
            list_str=''
            for i in value:
                #return_list.append(decode_attr(value,i))
                list_str=list_str+self.encode_attr(value,i)+','
            #print return_list
            return '[%s]'%list_str[:-1]
        elif type(value)==type(datetime.datetime.now()):
            return '"%s"'%str(value)
        elif '__class__' in dir(value):
            return self.encode_object(value)
        return ''


    def encode_object(self,tobject):
        value_list=dir(tobject)
        #print value_list
        json_str=''
        for svalue in value_list:
            js_str=self.encode_attr(tobject,svalue)
            if js_str:
                json_str+='"%s":%s,'%(svalue,js_str)
        json_str=json_str[:-1]
        return "{%s}"%json_str

    def dumps(self,obj):
        json_str=self.encode_object(obj)
        #print json_str,'#####'
        #json_str=json_str.replace("'",'"')
        return json_str
    ##############################################################

    def cnext(self):
        return self.content[self.i]
    def get_next(self):
        if self.i<len(self.content):
            c=self.cnext()
            self.i+=1
            return c
        return None

    def get_name(self):                             #get name
        v_name=''
        c=self.get_next()
        while c!='"' and c!=None:
            c=self.get_next()
            pass
        while True:
            c=self.strip_space()
            if c=='\\':
                self.get_next()
                continue
            elif c=='"':
                break
            v_name+=c
        #print v_name
        return v_name.strip()

    def get_str(self):                              #get value
        v_value=''
        while True:
            c=self.get_next()
            if c=='"':
                break
            elif c=='\\':
                tc=self.get_next()
                if tc=='u':                         #unicode
                    hexc=''
                    while True:
                        tcc=self.get_next()
                        if tcc.lower()  in self.hex_sign:
                            hexc+=tcc
                            if len(hexc)>=4:
                                v_value+=unichr(eval('0x'+hexc))
                                break
                        else:
                            v_value+=c
                            v_value+=tc
                            v_value+=hexc
                            break
                else:
                    v_value+=c
                    v_value+=tc
            else:
                v_value+=c
        return v_value
    
    def get_none(self,c):                              #get value
        v_value=c
        while True:
            c=self.get_next()
            if c in self.end_sign:
                self.i-=1
                break
            else:
                v_value+=c
        v_value=v_value.strip()
        if v_value=='null':
            return None
        else:
            raise Exception('None type error in positon: %d'%self.i)
    
    def get_bool(self,c):
        cc=c
        while True:
            tc=self.get_next()
            if tc in self.end_sign:
                self.i-=1
                break
            else:
                cc+=tc
        if cc.strip()=='true':
            return True
        elif cc.strip()=='false':
            return False
        else:
            print cc
            raise Exception('bool type error in position: %d'%self.i)
    def get_num(self,c):
        s_num=c
        while True:
            cc=self.get_next()
            if cc in self.end_sign:
                self.i-=1
                break
            else:
                s_num+=cc
        return eval(s_num.strip())
    def get_list(self):
        r_list=[]
        while True:
            c=self.strip_space()
            if c=='"':
                v_value=self.get_str()
            elif c in 'tf':
                v_value=self.get_bool(c)
            elif c in '-1234567890':
                v_value=self.get_num(c)
            elif c=='n':
                v_value=self.get_none(c)
            elif c=='[':
                v_value=self.get_list()
            elif c=='{':
                v_value=self.get_object()
            r_list.append(v_value)
            c=self.strip_space()
            if c==',':
                continue
            elif c==']':
                return r_list
            else:
                print v_value,r_list
                print self.content[self.i-20:self.i+20]
                print c,'----',self.content[self.i]
                raise Exception('list type error in position: %d'%self.i)
    
    def strip_space(self):
        while True:
            c=self.get_next()
            if c not in ' \t\n\r\v\f':
                return c

    def get_object(self):
        obj=Object()
        while True:
            v_name=self.get_name()               #获得名称
            while self.get_next()!=':':          #过滤冒号
                pass
            c=self.strip_space()
            if c=='"':
                v_value=self.get_str()
            elif c in 'tf':
                v_value=self.get_bool(c)
            elif c in '-1234567890':
                v_value=self.get_num(c)
            elif c=='n':
                v_value=self.get_none(c)
            elif c=='[':
                v_value=self.get_list()
            elif c=='{':
                v_value=self.get_object()
            setattr(obj,v_name,v_value)
            #print v_name,v_value
            c=self.strip_space()
            if c==',':
                continue
            elif c=='}' or c==None:
                break
            else:
                print self.i,self.content[self.i-20:self.i],'sss',self.content[self.i:self.i+20]
                print c,self.i
                raise Exception(c)
        return obj

    def loads(self,json_str):
        self.content=self.decode_str(json_str.strip())
        self.i=0
        self.end_sign='",]}:'                            #end sign
        self.hex_sign='1234567890abcde'
        c=self.strip_space()
        if c=='{' or True:
            obj=self.get_object()
            return obj
        else:
            print 'error'
            raise Exception('error json string')
        
    def get_attr(self,obj,attr_str):
        if hasattr(obj,attr_str):
            return getattr(obj,attr_str)
        else:
            return None
    def set_attr(self,obj,v_name,v_value):
        setattr(obj,v_name,v_value)
        return obj
    def del_attr(self,obj,v_name):
        if hasattr(obj,v_name):
            _attr=getattr(obj,v_name)
            del _attr
            return obj
        
class C(object):
    c_cc='cc'
    c_list_c=['c','c']*5
class B(object):
    b_bb=9
    b_list_b=['b','b']
    #b_c=C()
    #b_list_c_object=[C()]*50
    #b_bzn='中文'
class A(object):
    '''int、string、Boolean、long、double,arraylist、object、DateTime、'''
    a_i=1
    a_s='a'
    #a_szn='中文'
    a_b=True
    a_li=[1,2,3]
    a_o=B()
    a_dt=datetime.datetime.now()
    a_l=9999L
    a_f=1.1

    def say_hi(self):
        print 'hi'
    def set_ii(self):
        self.ii=123

a=A()
a.a_n=None
a.set_ii()
mj=Myjson()
json_str=mj.dumps(a)
print json_str
json_str=r'''
{ "a_b": true,
"a_dt":"2012-09-27 16:48:53.328000","a_s":"\p123s\u4e2d\u6587",
"a_f":1.11,"a_i":11,"a_l":9999,"a_li":[1,2,3],"a_n":null,"a_o":{"b_bb":9,"b_list_b":["b","b"]},"ii":123}
'''
start=datetime.datetime.now()
f=open('d:/tmp/22.txt')

json_str=f.read()
f.close()

obj=mj.loads(json_str)
end=datetime.datetime.now()

print end-start
print '-------------------------------'
'''
for v in dir(obj):
    if not v.startswith('__'):
        if isinstance(getattr(obj,v),Object):
            print getattr(obj,v)
            pass
        else:
            print v,getattr(obj,v)
            pass
'''





